home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / flex 2.4.6 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-21  |  24.6 KB  |  1,005 lines  |  [TEXT/MPS ]

  1. /* flex - tool to generate fast lexical analyzers */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. #ifndef lint
  30. char copyright[] =
  31. "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
  32.  All rights reserved.\n";
  33. #endif /* not lint */
  34.  
  35. /* $Header: main.c,v 1.2 94/01/04 14:33:11 vern Exp $ */
  36.  
  37.  
  38. #include "flexdef.h"
  39. #include "version.h"
  40.  
  41. #if defined(MPW) && defined(__STDC__)
  42. void fsetfileinfo (char *filename, unsigned long newcreator, unsigned long newtype);
  43. #endif
  44.  
  45. static char flex_version[] = FLEX_VERSION;
  46.  
  47.  
  48. /* declare functions that have forward references */
  49.  
  50. void flexinit PROTO((int, char**));
  51. void readin PROTO((void));
  52. void set_up_initial_allocations PROTO((void));
  53.  
  54.  
  55. /* these globals are all defined and commented in flexdef.h */
  56. int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt;
  57. int interactive, caseins, lex_compat, useecs, fulltbl, usemecs;
  58. int fullspd, gen_line_dirs, performance_report, backing_up_report;
  59. int C_plus_plus, long_align, use_read, yytext_is_array, csize;
  60. int yymore_used, reject, real_reject, continued_action;
  61. int yymore_really_used, reject_really_used;
  62. int datapos, dataline, linenum;
  63. FILE *skelfile = NULL;
  64. int skel_ind = 0;
  65. char *action_array;
  66. int action_size, defs1_offset, prolog_offset, action_offset, action_index;
  67. char *infilename = NULL;
  68. int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
  69. int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
  70. int current_mns, num_rules, num_eof_rules, default_rule;
  71. int current_max_rules, lastnfa;
  72. int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2;
  73. int *accptnum, *assoc_rule, *state_type;
  74. int *rule_type, *rule_linenum, *rule_useful;
  75. int current_state_type;
  76. int variable_trailing_context_rules;
  77. int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
  78. int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
  79. int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
  80. int tecbck[CSIZE + 1];
  81. int lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc;
  82. char **scname;
  83. int current_max_dfa_size, current_max_xpairs;
  84. int current_max_template_xpairs, current_max_dfas;
  85. int lastdfa, *nxt, *chk, *tnxt;
  86. int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz;
  87. union dfaacc_union *dfaacc;
  88. int *accsiz, *dhash, numas;
  89. int numsnpairs, jambase, jamstate;
  90. int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse;
  91. int current_max_ccl_tbl_size;
  92. Char *ccltbl;
  93. char nmstr[MAXLINE];
  94. int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
  95. int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
  96. int num_backing_up, bol_needed;
  97. FILE *backing_up_file;
  98. int end_of_buffer_state;
  99. char **input_files;
  100. int num_input_files;
  101. char *program_name;
  102.  
  103. #ifndef SHORT_FILE_NAMES
  104. static char *outfile_template = "lex.%s.%s";
  105. #else
  106. static char *outfile_template = "lex%s.%s";
  107. #endif
  108. static char outfile_path[64];
  109.  
  110. static int outfile_created = 0;
  111. static int use_stdout;
  112. static char *skelname = NULL;
  113. static char *prefix = "yy";
  114.  
  115.  
  116. int main( argc, argv )
  117. int argc;
  118. char **argv;
  119.     {
  120.     int i;
  121.  
  122.     flexinit( argc, argv );
  123.  
  124.     readin();
  125.  
  126.     ntod();
  127.  
  128.     for ( i = 1; i <= num_rules; ++i )
  129.         if ( ! rule_useful[i] && i != default_rule )
  130.             line_warning( "rule cannot be matched",
  131.                     rule_linenum[i] );
  132.  
  133.     if ( spprdflt && ! reject && rule_useful[default_rule] )
  134.         line_warning( "-s option given but default rule can be matched",
  135.             rule_linenum[default_rule] );
  136.  
  137.     /* Generate the C state transition tables from the DFA. */
  138.     make_tables();
  139.  
  140.     /* Note, flexend does not return.  It exits with its argument
  141.      * as status.
  142.      */
  143.     flexend( 0 );
  144.  
  145.     return 0;    /* keep compilers/lint happy */
  146.     }
  147.  
  148.  
  149. /* flexend - terminate flex
  150.  *
  151.  * note
  152.  *    This routine does not return.
  153.  */
  154.  
  155. void flexend( exit_status )
  156. int exit_status;
  157.  
  158.     {
  159.     int tblsiz;
  160.     int unlink();
  161.  
  162.     if ( skelfile != NULL )
  163.         {
  164.         if ( ferror( skelfile ) )
  165.             flexfatal(
  166.                 "error occurred when reading skeleton file" );
  167.  
  168.         else if ( fclose( skelfile ) )
  169.             flexfatal(
  170.                 "error occurred when closing skeleton file" );
  171.         }
  172.  
  173.     if ( exit_status != 0 && outfile_created )
  174.         {
  175.         if ( ferror( stdout ) )
  176.             flexfatal( "error occurred when writing output file" );
  177.  
  178.         else if ( fclose( stdout ) )
  179.             flexfatal( "error occurred when closing output file" );
  180.  
  181.         else if ( unlink( outfile_path ) )
  182.             flexfatal( "error occurred when deleting output file" );
  183.         }
  184.  
  185.     if ( backing_up_report && backing_up_file )
  186.         {
  187.         if ( num_backing_up == 0 )
  188.             fprintf( backing_up_file, "No backing up.\n" );
  189.         else if ( fullspd || fulltbl )
  190.             fprintf( backing_up_file,
  191.                 "%d backing up (non-accepting) states.\n",
  192.                 num_backing_up );
  193.         else
  194.             fprintf( backing_up_file,
  195.                 "Compressed tables always back up.\n" );
  196.  
  197.         if ( ferror( backing_up_file ) )
  198.             flexfatal( "error occurred when writing backup file" );
  199.  
  200.         else if ( fclose( backing_up_file ) )
  201.             flexfatal( "error occurred when closing backup file" );
  202.         }
  203.  
  204.     if ( printstats )
  205.         {
  206.         fprintf( stderr, "%s version %s usage statistics:\n",
  207.             program_name, flex_version );
  208.  
  209.         fprintf( stderr, "  scanner options: -" );
  210.  
  211.         if ( C_plus_plus )
  212.             putc( '+', stderr );
  213.         if ( backing_up_report )
  214.             putc( 'b', stderr );
  215.         if ( ddebug )
  216.             putc( 'd', stderr );
  217.         if ( caseins )
  218.             putc( 'i', stderr );
  219.         if ( lex_compat )
  220.             putc( 'l', stderr );
  221.         if ( performance_report > 0 )
  222.             putc( 'p', stderr );
  223.         if ( performance_report > 1 )
  224.             putc( 'p', stderr );
  225.         if ( spprdflt )
  226.             putc( 's', stderr );
  227.         if ( use_stdout )
  228.             putc( 't', stderr );
  229.         if ( printstats )
  230.             putc( 'v', stderr );    /* always true! */
  231.         if ( nowarn )
  232.             putc( 'w', stderr );
  233.         if ( ! interactive )
  234.             putc( 'B', stderr );
  235.         if ( interactive )
  236.             putc( 'I', stderr );
  237.         if ( ! gen_line_dirs )
  238.             putc( 'L', stderr );
  239.         if ( trace )
  240.             putc( 'T', stderr );
  241.         if ( csize == 128 )
  242.             putc( '7', stderr );
  243.         else
  244.             putc( '8', stderr );
  245.  
  246.         fprintf( stderr, " -C" );
  247.  
  248.         if ( long_align )
  249.             putc( 'a', stderr );
  250.         if ( fulltbl )
  251.             putc( 'f', stderr );
  252.         if ( fullspd )
  253.             putc( 'F', stderr );
  254.         if ( useecs )
  255.             putc( 'e', stderr );
  256.         if ( usemecs )
  257.             putc( 'm', stderr );
  258.         if ( use_read )
  259.             putc( 'r', stderr );
  260.  
  261.         if ( skelname )
  262.             fprintf( stderr, " -S%s", skelname );
  263.  
  264.         if ( strcmp( prefix, "yy" ) )
  265.             fprintf( stderr, " -P%s", prefix );
  266.  
  267.         putc( '\n', stderr );
  268.  
  269.         fprintf( stderr, "  %d/%d NFA states\n", lastnfa, current_mns );
  270.         fprintf( stderr, "  %d/%d DFA states (%d words)\n", lastdfa,
  271.             current_max_dfas, totnst );
  272.         fprintf( stderr, "  %d rules\n",
  273.         num_rules + num_eof_rules - 1 /* - 1 for def. rule */ );
  274.  
  275.         if ( num_backing_up == 0 )
  276.             fprintf( stderr, "  No backing up\n" );
  277.         else if ( fullspd || fulltbl )
  278.             fprintf( stderr,
  279.                 "  %d backing-up (non-accepting) states\n",
  280.                 num_backing_up );
  281.         else
  282.             fprintf( stderr,
  283.                 "  Compressed tables always back-up\n" );
  284.  
  285.         if ( bol_needed )
  286.             fprintf( stderr,
  287.                 "  Beginning-of-line patterns used\n" );
  288.  
  289.         fprintf( stderr, "  %d/%d start conditions\n", lastsc,
  290.             current_max_scs );
  291.         fprintf( stderr,
  292.             "  %d epsilon states, %d double epsilon states\n",
  293.             numeps, eps2 );
  294.  
  295.         if ( lastccl == 0 )
  296.             fprintf( stderr, "  no character classes\n" );
  297.         else
  298.             fprintf( stderr,
  299.     "  %d/%d character classes needed %d/%d words of storage, %d reused\n",
  300.                 lastccl, current_maxccls,
  301.                 cclmap[lastccl] + ccllen[lastccl],
  302.                 current_max_ccl_tbl_size, cclreuse );
  303.  
  304.         fprintf( stderr, "  %d state/nextstate pairs created\n",
  305.             numsnpairs );
  306.         fprintf( stderr, "  %d/%d unique/duplicate transitions\n",
  307.             numuniq, numdup );
  308.  
  309.         if ( fulltbl )
  310.             {
  311.             tblsiz = lastdfa * numecs;
  312.             fprintf( stderr, "  %d table entries\n", tblsiz );
  313.             }
  314.  
  315.         else
  316.             {
  317.             tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
  318.  
  319.             fprintf( stderr, "  %d/%d base-def entries created\n",
  320.                 lastdfa + numtemps, current_max_dfas );
  321.             fprintf( stderr,
  322.                 "  %d/%d (peak %d) nxt-chk entries created\n",
  323.                 tblend, current_max_xpairs, peakpairs );
  324.             fprintf( stderr,
  325.             "  %d/%d (peak %d) template nxt-chk entries created\n",
  326.                 numtemps * nummecs, current_max_template_xpairs,
  327.                 numtemps * numecs );
  328.             fprintf( stderr, "  %d empty table entries\n", nummt );
  329.             fprintf( stderr, "  %d protos created\n", numprots );
  330.             fprintf( stderr, "  %d templates created, %d uses\n",
  331.                 numtemps, tmpuses );
  332.             }
  333.  
  334.         if ( useecs )
  335.             {
  336.             tblsiz = tblsiz + csize;
  337.             fprintf( stderr,
  338.                 "  %d/%d equivalence classes created\n",
  339.                 numecs, csize );
  340.             }
  341.  
  342.         if ( usemecs )
  343.             {
  344.             tblsiz = tblsiz + numecs;
  345.             fprintf( stderr,
  346.                 "  %d/%d meta-equivalence classes created\n",
  347.                 nummecs, csize );
  348.             }
  349.  
  350.         fprintf( stderr,
  351.             "  %d (%d saved) hash collisions, %d DFAs equal\n",
  352.             hshcol, hshsave, dfaeql );
  353.         fprintf( stderr, "  %d sets of reallocations needed\n",
  354.             num_reallocs );
  355.         fprintf( stderr, "  %d total table entries needed\n", tblsiz );
  356.         }
  357.  
  358. #ifndef VMS
  359.     exit( exit_status );
  360. #else
  361.     exit( exit_status + 1 );
  362. #endif
  363.     }
  364.  
  365.  
  366. /* flexinit - initialize flex */
  367.  
  368. void flexinit( argc, argv )
  369. int argc;
  370. char **argv;
  371.     {
  372.     int i, sawcmpflag;
  373.     int csize_given, interactive_given;
  374.     char *arg, *mktemp();
  375.  
  376.     printstats = syntaxerror = trace = spprdflt = caseins = false;
  377.     lex_compat = false;
  378.     C_plus_plus = backing_up_report = ddebug = fulltbl = fullspd = false;
  379.     long_align = nowarn = yymore_used = continued_action = reject = false;
  380.     yytext_is_array = yymore_really_used = reject_really_used = false;
  381.     gen_line_dirs = usemecs = useecs = true;
  382.     performance_report = 0;
  383.  
  384.     sawcmpflag = false;
  385.     use_read = use_stdout = false;
  386.     csize_given = false;
  387.     interactive_given = false;
  388.  
  389.     /* Initialize dynamic array for holding the rule actions. */
  390.     action_size = 2048;    /* default size of action array in bytes */
  391.     action_array = allocate_character_array( action_size );
  392.     defs1_offset = prolog_offset = action_offset = action_index = 0;
  393.     action_array[0] = '\0';
  394.  
  395.     program_name = argv[0];
  396.  
  397. #ifdef MPW
  398.     InitCursorCtl( NULL );
  399.     SpinCursor( 1 );
  400. #endif
  401.  
  402.     if ( program_name[0] != '\0' &&
  403.          program_name[strlen( program_name ) - 1] == '+' )
  404.         C_plus_plus = true;
  405.  
  406.     /* read flags */
  407.     for ( --argc, ++argv; argc ; --argc, ++argv )
  408.         {
  409.         if ( argv[0][0] != '-' || argv[0][1] == '\0' )
  410.             break;
  411.  
  412.         arg = argv[0];
  413.  
  414.         for ( i = 1; arg[i] != '\0'; ++i )
  415.             switch ( arg[i] )
  416.                 {
  417.                 case '+':
  418.                     C_plus_plus = true;
  419.                     break;
  420.  
  421.                 case 'B':
  422.                     interactive = false;
  423.                     interactive_given = true;
  424.                     break;
  425.  
  426.                 case 'b':
  427.                     backing_up_report = true;
  428.                     break;
  429.  
  430.                 case 'c':
  431.                     fprintf( stderr,
  432.     "%s: Assuming use of deprecated -c flag is really intended to be -C\n",
  433.                     program_name );
  434.  
  435.                     /* fall through */
  436.  
  437.                 case 'C':
  438.                     if ( i != 1 )
  439.                         flexerror(
  440.                     "-C flag must be given separately" );
  441.  
  442.                     if ( ! sawcmpflag )
  443.                         {
  444.                         useecs = false;
  445.                         usemecs = false;
  446.                         fulltbl = false;
  447.                         sawcmpflag = true;
  448.                         }
  449.  
  450.                     for ( ++i; arg[i] != '\0'; ++i )
  451.                         switch ( arg[i] )
  452.                             {
  453.                             case 'a':
  454.                                 long_align =
  455.                                     true;
  456.                                 break;
  457.  
  458.                             case 'e':
  459.                                 useecs = true;
  460.                                 break;
  461.  
  462.                             case 'F':
  463.                                 fullspd = true;
  464.                                 break;
  465.  
  466.                             case 'f':
  467.                                 fulltbl = true;
  468.                                 break;
  469.  
  470.                             case 'm':
  471.                                 usemecs = true;
  472.                                 break;
  473.  
  474.                             case 'r':
  475.                                 use_read = true;
  476.                                 break;
  477.  
  478.                             default:
  479.                                 lerrif(
  480.                         "unknown -C option '%c'",
  481.                                 (int) arg[i] );
  482.                                 break;
  483.                             }
  484.  
  485.                     goto get_next_arg;
  486.  
  487.                 case 'd':
  488.                     ddebug = true;
  489.                     break;
  490.  
  491.                 case 'f':
  492.                     useecs = usemecs = false;
  493.                     use_read = fulltbl = true;
  494.                     break;
  495.  
  496.                 case 'F':
  497.                     useecs = usemecs = false;
  498.                     use_read = fullspd = true;
  499.                     break;
  500.  
  501.                 case 'h':
  502.                     usage();
  503.                     exit( 0 );
  504.  
  505.                 case 'I':
  506.                     interactive = true;
  507.                     interactive_given = true;
  508.                     break;
  509.  
  510.                 case 'i':
  511.                     caseins = true;
  512.                     break;
  513.  
  514.                 case 'l':
  515.                     lex_compat = true;
  516.                     break;
  517.  
  518.                 case 'L':
  519.                     gen_line_dirs = false;
  520.                     break;
  521.  
  522.                 case 'n':
  523.                     /* Stupid do-nothing deprecated
  524.                      * option.
  525.                      */
  526.                     break;
  527.  
  528.                 case 'P':
  529.                     if ( i != 1 )
  530.                         flexerror(
  531.                     "-P flag must be given separately" );
  532.  
  533.                     prefix = arg + i + 1;
  534.                     goto get_next_arg;
  535.  
  536.                 case 'p':
  537.                     ++performance_report;
  538.                     break;
  539.  
  540.                 case 'S':
  541.                     if ( i != 1 )
  542.                         flexerror(
  543.                     "-S flag must be given separately" );
  544.  
  545.                     skelname = arg + i + 1;
  546.                     goto get_next_arg;
  547.  
  548.                 case 's':
  549.                     spprdflt = true;
  550.                     break;
  551.  
  552.                 case 't':
  553.                     use_stdout = true;
  554.                     break;
  555.  
  556.                 case 'T':
  557.                     trace = true;
  558.                     break;
  559.  
  560.                 case 'v':
  561.                     printstats = true;
  562.                     break;
  563.  
  564.                 case 'V':
  565.                     fprintf( stderr, "%s version %s\n",
  566.                         program_name, flex_version );
  567.                     exit( 0 );
  568.  
  569.                 case 'w':
  570.                     nowarn = true;
  571.                     break;
  572.  
  573.                 case '7':
  574.                     csize = 128;
  575.                     csize_given = true;
  576.                     break;
  577.  
  578.                 case '8':
  579.                     csize = CSIZE;
  580.                     csize_given = true;
  581.                     break;
  582.  
  583.                 default:
  584.                     fprintf( stderr,
  585.                         "%s: unknown flag '%c'\n",
  586.                         program_name, (int) arg[i] );
  587.                     usage();
  588.                     exit( 1 );
  589.                 }
  590.  
  591.         /* Used by -C, -S and -P flags in lieu of a "continue 2"
  592.          * control.
  593.          */
  594.         get_next_arg: ;
  595.         }
  596.  
  597.     if ( ! csize_given )
  598.         {
  599.         if ( (fulltbl || fullspd) && ! useecs )
  600.             csize = DEFAULT_CSIZE;
  601.         else
  602.             csize = CSIZE;
  603.         }
  604.  
  605.     if ( ! interactive_given )
  606.         {
  607.         if ( fulltbl || fullspd )
  608.             interactive = false;
  609.         else
  610.             interactive = true;
  611.         }
  612.  
  613.     if ( lex_compat )
  614.         {
  615.         if ( C_plus_plus )
  616.             flexerror( "Can't use -+ with -l option" );
  617.  
  618.         if ( fulltbl || fullspd )
  619.             flexerror( "Can't use -f or -F with -l option" );
  620.  
  621.         /* Don't rely on detecting use of yymore() and REJECT,
  622.          * just assume they'll be used.
  623.          */
  624.         yymore_really_used = reject_really_used = true;
  625.  
  626.         yytext_is_array = true;
  627.         use_read = false;
  628.         }
  629.  
  630.     if ( (fulltbl || fullspd) && usemecs )
  631.         flexerror( "-Cf/-CF and -Cm don't make sense together" );
  632.  
  633.     if ( (fulltbl || fullspd) && interactive )
  634.         flexerror( "-Cf/-CF and -I are incompatible" );
  635.  
  636.     if ( fulltbl && fullspd )
  637.         flexerror( "-Cf and -CF are mutually exclusive" );
  638.  
  639.     if ( C_plus_plus && fullspd )
  640.         flexerror( "Can't use -+ with -CF option" );
  641.  
  642.     if ( ! use_stdout )
  643.         {
  644.         FILE *prev_stdout;
  645.         char *suffix;
  646.  
  647.         if ( C_plus_plus )
  648.             suffix = "cc";
  649.         else
  650.             suffix = "c";
  651.  
  652.         sprintf( outfile_path, outfile_template, prefix, suffix );
  653.  
  654.         prev_stdout = freopen( outfile_path, "w", stdout );
  655.  
  656.         if ( prev_stdout == NULL )
  657.             lerrsf( "could not create %s", outfile_path );
  658.  
  659.         outfile_created = 1;
  660. #ifdef MPW
  661.         fsetfileinfo( outfile_path, 'MPS ', 'TEXT' );
  662. #endif
  663.         }
  664.  
  665.     num_input_files = argc;
  666.     input_files = argv;
  667.     set_input_file( num_input_files > 0 ? input_files[0] : NULL );
  668.  
  669.     if ( backing_up_report )
  670.         {
  671. #ifndef SHORT_FILE_NAMES
  672.         backing_up_file = fopen( "lex.backup", "w" );
  673. #else
  674.         backing_up_file = fopen( "lex.bck", "w" );
  675. #endif
  676.  
  677.         if ( backing_up_file == NULL )
  678.             flexerror( "could not create lex.backup" );
  679. #ifdef MPW
  680.         fsetfileinfo( "lex.backup", 'MPS ', 'TEXT' );
  681. #endif
  682.         }
  683.  
  684.     else
  685.         backing_up_file = NULL;
  686.  
  687.  
  688.     lastccl = 0;
  689.     lastsc = 0;
  690.  
  691.     if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL )
  692.         lerrsf( "can't open skeleton file %s", skelname );
  693.  
  694.     if ( strcmp( prefix, "yy" ) )
  695.         {
  696. #define GEN_PREFIX(name) printf( "#define yy%s %s%s\n", name, prefix, name );
  697.         GEN_PREFIX( "FlexLexer" );
  698.         GEN_PREFIX( "_create_buffer" );
  699.         GEN_PREFIX( "_delete_buffer" );
  700.         GEN_PREFIX( "_flex_debug" );
  701.         GEN_PREFIX( "_init_buffer" );
  702.         GEN_PREFIX( "_load_buffer_state" );
  703.         GEN_PREFIX( "_switch_to_buffer" );
  704.         GEN_PREFIX( "in" );
  705.         GEN_PREFIX( "leng" );
  706.         GEN_PREFIX( "lex" );
  707.         GEN_PREFIX( "out" );
  708.         GEN_PREFIX( "restart" );
  709.         GEN_PREFIX( "text" );
  710.         GEN_PREFIX( "wrap" );
  711.         printf( "\n" );
  712.         }
  713.  
  714.  
  715.     lastdfa = lastnfa = 0;
  716.     num_rules = num_eof_rules = default_rule = 0;
  717.     numas = numsnpairs = tmpuses = 0;
  718.     numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
  719.     numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
  720.     num_backing_up = onesp = numprots = 0;
  721.     variable_trailing_context_rules = bol_needed = false;
  722.  
  723.     linenum = sectnum = 1;
  724.     firstprot = NIL;
  725.  
  726.     /* Used in mkprot() so that the first proto goes in slot 1
  727.      * of the proto queue.
  728.      */
  729.     lastprot = 1;
  730.  
  731.     if ( useecs )
  732.         {
  733.         /* Set up doubly-linked equivalence classes. */
  734.  
  735.         /* We loop all the way up to csize, since ecgroup[csize] is
  736.          * the position used for NUL characters.
  737.          */
  738.         ecgroup[1] = NIL;
  739.  
  740.         for ( i = 2; i <= csize; ++i )
  741.             {
  742.             ecgroup[i] = i - 1;
  743.             nextecm[i - 1] = i;
  744.             }
  745.  
  746.         nextecm[csize] = NIL;
  747.         }
  748.  
  749.     else
  750.         {
  751.         /* Put everything in its own equivalence class. */
  752.         for ( i = 1; i <= csize; ++i )
  753.             {
  754.             ecgroup[i] = i;
  755.             nextecm[i] = BAD_SUBSCRIPT;    /* to catch errors */
  756.             }
  757.         }
  758.  
  759.     set_up_initial_allocations();
  760.     }
  761.  
  762.  
  763. /* readin - read in the rules section of the input file(s) */
  764.  
  765. void readin()
  766.     {
  767.     skelout();
  768.  
  769.     line_directive_out( (FILE *) 0 );
  770.  
  771.     if ( yyparse() )
  772.         {
  773.         pinpoint_message( "fatal parse error" );
  774.         flexend( 1 );
  775.         }
  776.  
  777.     if ( syntaxerror )
  778.         flexend( 1 );
  779.  
  780.     if ( yymore_really_used == REALLY_USED )
  781.         yymore_used = true;
  782.     else if ( yymore_really_used == REALLY_NOT_USED )
  783.         yymore_used = false;
  784.  
  785.     if ( reject_really_used == REALLY_USED )
  786.         reject = true;
  787.     else if ( reject_really_used == REALLY_NOT_USED )
  788.         reject = false;
  789.  
  790.     if ( performance_report > 0 )
  791.         {
  792.         if ( lex_compat )
  793.             {
  794.             fprintf( stderr,
  795. "-l AT&T lex compatibility option entails a large performance penalty\n" );
  796.             fprintf( stderr,
  797. " and may be the actual source of other reported performance penalties\n" );
  798.             }
  799.  
  800.         if ( performance_report > 1 )
  801.             {
  802.             if ( interactive )
  803.                 fprintf( stderr,
  804.         "-I (interactive) entails a minor performance penalty\n" );
  805.  
  806.             if ( yymore_used )
  807.                 fprintf( stderr,
  808.             "yymore() entails a minor performance penalty\n" );
  809.             }
  810.  
  811.         if ( reject )
  812.             fprintf( stderr,
  813.             "REJECT entails a large performance penalty\n" );
  814.  
  815.         if ( variable_trailing_context_rules )
  816.             fprintf( stderr,
  817. "Variable trailing context rules entail a large performance penalty\n" );
  818.         }
  819.  
  820.     if ( reject )
  821.         real_reject = true;
  822.  
  823.     if ( variable_trailing_context_rules )
  824.         reject = true;
  825.  
  826.     if ( (fulltbl || fullspd) && reject )
  827.         {
  828.         if ( real_reject )
  829.             flexerror( "REJECT cannot be used with -f or -F" );
  830.         else
  831.             flexerror(
  832.     "variable trailing context rules cannot be used with -f or -F" );
  833.         }
  834.  
  835.     if ( csize == 256 )
  836.         puts( "typedef unsigned char YY_CHAR;" );
  837.     else
  838.         puts( "typedef char YY_CHAR;" );
  839.  
  840.     if ( C_plus_plus )
  841.         {
  842.         puts( "#define yytext_ptr yytext" );
  843.  
  844.         if ( interactive )
  845.             puts( "#define YY_INTERACTIVE" );
  846.         }
  847.  
  848.     if ( fullspd )
  849.         printf(
  850.         "typedef const struct yy_trans_info *yy_state_type;\n" );
  851.     else if ( ! C_plus_plus )
  852.         printf( "typedef int yy_state_type;\n" );
  853.  
  854.     if ( reject )
  855.         printf( "\n#define YY_USES_REJECT\n" );
  856.  
  857.     if ( ddebug )
  858.         puts( "\n#define FLEX_DEBUG" );
  859.  
  860.     if ( lex_compat )
  861.         {
  862.         printf( "FILE *yyin = stdin, *yyout = stdout;\n" );
  863.         printf( "extern int yylineno;\n" );
  864.         printf( "int yylineno = 1;\n" );
  865.         }
  866.     else if ( ! C_plus_plus )
  867.         printf( "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;\n" );
  868.  
  869.     if ( C_plus_plus )
  870.         printf( "\n#include <FlexLexer.h>\n" );
  871.  
  872.     else
  873.         {
  874.         if ( yytext_is_array )
  875.             puts( "extern char yytext[];\n" );
  876.  
  877.         else
  878.             {
  879.             puts( "extern char *yytext;" );
  880.             puts( "#define yytext_ptr yytext" );
  881.             }
  882.         }
  883.  
  884.     if ( useecs )
  885.         numecs = cre8ecs( nextecm, ecgroup, csize );
  886.     else
  887.         numecs = csize;
  888.  
  889.     /* Now map the equivalence class for NUL to its expected place. */
  890.     ecgroup[0] = ecgroup[csize];
  891.     NUL_ec = ABS( ecgroup[0] );
  892.  
  893.     if ( useecs )
  894.         ccl2ecl();
  895.     }
  896.  
  897.  
  898. /* set_up_initial_allocations - allocate memory for internal tables */
  899.  
  900. void set_up_initial_allocations()
  901.     {
  902.     current_mns = INITIAL_MNS;
  903.     firstst = allocate_integer_array( current_mns );
  904.     lastst = allocate_integer_array( current_mns );
  905.     finalst = allocate_integer_array( current_mns );
  906.     transchar = allocate_integer_array( current_mns );
  907.     trans1 = allocate_integer_array( current_mns );
  908.     trans2 = allocate_integer_array( current_mns );
  909.     accptnum = allocate_integer_array( current_mns );
  910.     assoc_rule = allocate_integer_array( current_mns );
  911.     state_type = allocate_integer_array( current_mns );
  912.  
  913.     current_max_rules = INITIAL_MAX_RULES;
  914.     rule_type = allocate_integer_array( current_max_rules );
  915.     rule_linenum = allocate_integer_array( current_max_rules );
  916.     rule_useful = allocate_integer_array( current_max_rules );
  917.  
  918.     current_max_scs = INITIAL_MAX_SCS;
  919.     scset = allocate_integer_array( current_max_scs );
  920.     scbol = allocate_integer_array( current_max_scs );
  921.     scxclu = allocate_integer_array( current_max_scs );
  922.     sceof = allocate_integer_array( current_max_scs );
  923.     scname = allocate_char_ptr_array( current_max_scs );
  924.     actvsc = allocate_integer_array( current_max_scs );
  925.  
  926.     current_maxccls = INITIAL_MAX_CCLS;
  927.     cclmap = allocate_integer_array( current_maxccls );
  928.     ccllen = allocate_integer_array( current_maxccls );
  929.     cclng = allocate_integer_array( current_maxccls );
  930.  
  931.     current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
  932.     ccltbl = allocate_Character_array( current_max_ccl_tbl_size );
  933.  
  934.     current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
  935.  
  936.     current_max_xpairs = INITIAL_MAX_XPAIRS;
  937.     nxt = allocate_integer_array( current_max_xpairs );
  938.     chk = allocate_integer_array( current_max_xpairs );
  939.  
  940.     current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
  941.     tnxt = allocate_integer_array( current_max_template_xpairs );
  942.  
  943.     current_max_dfas = INITIAL_MAX_DFAS;
  944.     base = allocate_integer_array( current_max_dfas );
  945.     def = allocate_integer_array( current_max_dfas );
  946.     dfasiz = allocate_integer_array( current_max_dfas );
  947.     accsiz = allocate_integer_array( current_max_dfas );
  948.     dhash = allocate_integer_array( current_max_dfas );
  949.     dss = allocate_int_ptr_array( current_max_dfas );
  950.     dfaacc = allocate_dfaacc_union( current_max_dfas );
  951.  
  952.     nultrans = (int *) 0;
  953.     }
  954.  
  955.  
  956. void usage()
  957.     {
  958.     fprintf( stderr,
  959. "%s [-bcdfhilnpstvwBFILTV78+ -C[aefFmr] -Pprefix -Sskeleton] [file ...]\n",
  960.         program_name );
  961.  
  962.     fprintf( stderr,
  963.         "\t-b  generate backing-up information to lex.backup\n" );
  964.     fprintf( stderr, "\t-c  do-nothing POSIX option\n" );
  965.     fprintf( stderr, "\t-d  turn on debug mode in generated scanner\n" );
  966.     fprintf( stderr, "\t-f  generate fast, large scanner\n" );
  967.     fprintf( stderr, "\t-h  produce this help message\n" );
  968.     fprintf( stderr, "\t-i  generate case-insensitive scanner\n" );
  969.     fprintf( stderr, "\t-l  maximal compatibility with original lex\n" );
  970.     fprintf( stderr, "\t-n  do-nothing POSIX option\n" );
  971.     fprintf( stderr, "\t-p  generate performance report to stderr\n" );
  972.     fprintf( stderr,
  973.         "\t-s  suppress default rule to ECHO unmatched text\n" );
  974.     fprintf( stderr,
  975.     "\t-t  write generated scanner on stdout instead of lex.yy.c\n" );
  976.     fprintf( stderr,
  977.         "\t-v  write summary of scanner statistics to stderr\n" );
  978.     fprintf( stderr, "\t-w  do not generate warnings\n" );
  979.     fprintf( stderr, "\t-B  generate batch scanner (opposite of -I)\n" );
  980.     fprintf( stderr,
  981.         "\t-F  use alternative fast scanner representation\n" );
  982.     fprintf( stderr,
  983.         "\t-I  generate interactive scanner (opposite of -B)\n" );
  984.     fprintf( stderr, "\t-L  suppress #line directives in scanner\n" );
  985.     fprintf( stderr, "\t-T  %s should run in trace mode\n", program_name );
  986.     fprintf( stderr, "\t-V  report %s version\n", program_name );
  987.     fprintf( stderr, "\t-7  generate 7-bit scanner\n" );
  988.     fprintf( stderr, "\t-8  generate 8-bit scanner\n" );
  989.     fprintf( stderr, "\t-+  generate C++ scanner class\n" );
  990.     fprintf( stderr,
  991.     "\t-C  specify degree of table compression (default is -Cem):\n" );
  992.     fprintf( stderr,
  993.     "\t\t-Ca  trade off larger tables for better memory alignment\n" );
  994.     fprintf( stderr, "\t\t-Ce  construct equivalence classes\n" );
  995.     fprintf( stderr,
  996.     "\t\t-Cf  do not compress scanner tables; use -f representation\n" );
  997.     fprintf( stderr,
  998.     "\t\t-CF  do not compress scanner tables; use -F representation\n" );
  999.     fprintf( stderr, "\t\t-Cm  construct meta-equivalence classes\n" );
  1000.     fprintf( stderr,
  1001.         "\t\t-Cr  use read() instead of stdio for scanner input\n" );
  1002.     fprintf( stderr, "\t-P  specify scanner prefix other than \"yy\"\n" );
  1003.     fprintf( stderr, "\t-S  specify skeleton file\n" );
  1004.     }
  1005.